package com.cblz.bd.server.core.controller;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.cblz.bd.common.core.constant.AdminLoginConstant;
import com.cblz.bd.common.core.constant.ResponseStatusCode;
import com.cblz.bd.common.core.entity.BaAdmin;
import com.cblz.bd.common.core.entity.system.MenuTree;
import com.cblz.bd.common.core.exception.BdAdminException;
import com.cblz.bd.common.core.exception.ValidateCodeException;
import com.cblz.bd.common.core.utils.ResultResponse;
import com.cblz.bd.server.core.annotation.AdminApiController;
import com.cblz.bd.server.core.annotation.LoginLog;
import com.cblz.bd.server.core.entity.LoginParams;
import com.cblz.bd.server.core.entity.vo.BdAdminTokenVO;
import com.cblz.bd.server.core.service.BaAdminService;
import com.cblz.bd.server.core.service.BaConfigService;
import com.cblz.bd.server.core.service.BaMenuRuleService;
import com.cblz.bd.server.utils.BdCaptchaUtil;
import io.vavr.control.Option;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * {@code @Name:} BaAdminController
 * {@code @Description: }
 * {@code @Author:} by yanjieping
 * {@code @CreateDate:} 2022/11/4 - 周五
 */
@RestController
@RequiredArgsConstructor
@AdminApiController("user")
public class BaAdminController {

    private final BdCaptchaUtil bdCaptchaUtil;
    private final BaAdminService baAdminService;
    private final BaMenuRuleService baMenuRuleService;
    private final BaConfigService baConfigService;

    @PostMapping("login")
    @LoginLog(description = "登录")
    public ResultResponse login(@RequestBody(required = false) LoginParams loginParams) throws ValidateCodeException {
        if (null == loginParams)
            return new ResultResponse().message(ResponseStatusCode.ERROR.getStatusCode(), "登录参数不能为空");

        SaTokenInfo saTokenInfo = baAdminService.usernamePasswordCheck(loginParams);
        if (null != saTokenInfo) {
            BdAdminTokenVO bdAdminTokenVO = BeanUtil.copyProperties(baAdminService.getById(saTokenInfo.getLoginId().toString()), BdAdminTokenVO.class);
            BeanUtil.copyProperties(saTokenInfo, bdAdminTokenVO);
            bdAdminTokenVO.setToken(saTokenInfo.getTokenValue());
            // 登录成功，让验证码失效
            bdCaptchaUtil.delCaptcha(loginParams.getKey());

            StpUtil.getSession().set(AdminLoginConstant.SESSION.getValue() + StpUtil.getLoginId(), bdAdminTokenVO);

            String userInfoSession = new StringJoiner(":").add(AdminLoginConstant.SESSION.getValue()).add(saTokenInfo.getLoginId().toString()).add(saTokenInfo.getTokenValue()).toString();

            SaSession session = SaSessionCustomUtil.getSessionById(userInfoSession);
            session.set(userInfoSession, bdAdminTokenVO);

            return new ResultResponse().data("登录成功", Objects.requireNonNull(new ResultResponse().put("userinfo", bdAdminTokenVO)).put("routePath", AdminLoginConstant.ROUTE_PATH.getValue()));
        }

        return new ResultResponse().message(ResponseStatusCode.ERROR.getStatusCode(), "用户名和密码不正确");
    }

    @PostMapping("index")
    public ResultResponse index() {
        List<MenuTree> menus = baMenuRuleService.findMenuByLoginId(Integer.valueOf(StpUtil.getLoginId().toString()));
        BaAdmin baAdmin = Option.of(baAdminService.getById(StpUtil.getLoginId().toString())).getOrElseThrow(() -> {
            throw new BdAdminException("查不到当前登录ID的信息:" + StpUtil.getLoginId());
        });
        if (menus.isEmpty()) return new ResultResponse().message(ResponseStatusCode.ERROR.getStatusCode(), "空的");

        return new ResultResponse().data(Map.of("menus", menus, "siteConfig", baConfigService.getInitConfig(), "adminInfo", Map.of("username", baAdmin.getUsername(), "nickname", baAdmin.getNickname(), "avatar", baAdmin.getAvatar(), "lastlogintime", baAdmin.getLastlogintime(), "super", true)));
    }

    @GetMapping("login")
    public ResultResponse testLogin() {
        return new ResultResponse().data(Map.of("captcha", Boolean.TRUE));
    }

    /**
     * 查询登录状态
     *
     * @return
     */
    @GetMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录：" + StpUtil.isLogin();
    }

    @GetMapping("logout")
    public void logout() {
        baAdminService.logout();
    }

    @DeleteMapping("clearCache")
    public ResultResponse clearCache() {
        baAdminService.clearCache();
        return new ResultResponse().message("缓存已清理，请刷新后台~");
    }

}
